/**
 * Tetromino.m
 * Cocoa Tetris
 *
 * Copyright 2009 Wei Yeh, Evelyn Yung. All rights reserved.
 */

#import "TetrisController.h"

@implementation Tetromino

-(id)init {
	if (![super init]) return nil;
	myColor = nil;
	myCells = [[NSMutableArray alloc] init];
	myBoard = tetrisBoard;
	myRotationCount = 0;
	return self;
}

-(id)initAtY:(unsigned int)y x:(unsigned int)x check:(bool)check
{	
	if (![self init]) return nil;
	
	if (!check) {
		myBoard = tetrisMiniBoard;
	}
	
	return self;
}

-(bool)setUp
{
	for (unsigned int i = 0; i < [myCells count]; i++) {
		if (![[myCells objectAtIndex:i] markWithTetromino:self]) {
			return NO;
		}
	}
	return YES;
}

+(Tetromino *)randomTetromino
{
	Tetromino *tetromino;
	unsigned int randomType = random() % 7;
	switch (randomType) {
		case 0:
			tetromino = [OBlock alloc];
			break;
		case 1:
			tetromino = [LBlock alloc];
			break;
		case 2:
			tetromino = [JBlock alloc];
			break;
		case 3:
			tetromino = [IBlock alloc];
			break;
		case 4:
			tetromino = [SBlock alloc];
			break;
		case 5:
			tetromino = [ZBlock alloc];
			break;
		case 6:
			tetromino = [TBlock alloc];
			break;
	}
	return tetromino;
}


-(NSColor *)color 
{
	return myColor;
}

+(CGFloat)size 
{
	return 20;
}

-(void)unmarkCell:(Cell *)cell
{
	[cell unmark];
	[myCells removeObject:cell];
}

/***** ROTATION *****/

-(void)rotate
{
	if ([self canRotate]) {
		[self moveToNewCells:[self transform:NO]];
	}
}

/***** MOVING *****/

-(void)moveDown 
{
	if ([self canMoveDown]) {
		[self moveToNewCells:[self moveByY:-1 x:0]];
	}
}

-(void)moveLeft
{
	if ([self canMoveLeft]) {
		[self moveToNewCells:[self moveByY:0 x:-1]];
	}
}

-(void)moveRight
{
	if ([self canMoveRight]) {
		[self moveToNewCells:[self moveByY:0 x:1]];
	}
}

-(void)drop
{
	while([self canMoveDown]) {
		[self moveToNewCells:[self moveByY:-1 x:0]];
	}
}

-(NSMutableArray *)transform:(BOOL)check
{
	return nil;
}


-(NSMutableArray *)moveByY:(unsigned int)y x:(unsigned int)x
{
	int arrX[] = {x,x,x,x};
	int arrY[] = {y,y,y,y};
	return [self moveByArrayY:arrY arrayX:arrX];
}

-(NSMutableArray *)moveByArrayY:(int *)arrY arrayX:(int *)arrX;
{
	NSMutableArray *newCells = [[NSMutableArray alloc] init];
	Cell *currentCell;
	unsigned int newY, newX;
	for (unsigned int i = 0; i < [myCells count]; i++) {
		currentCell = [myCells objectAtIndex:i];
		newY = [currentCell y] + arrY[i];
		newX = [currentCell x] + arrX[i];
		if (![tetrisBoard isInBoundsY:newY x:newX]) {
			return nil;
		}
		[newCells addObject:[tetrisBoard cellAtY:newY x:newX]];
	}
	return newCells;
}
	

-(void)moveToNewCells:(NSMutableArray *)newCells
{
	/* Unmark old cells. */
	for (unsigned int i = 0; i < [myCells count]; i++) {
		[[myCells objectAtIndex:i] unmark];
	}
	
	myCells = newCells;
	for (unsigned int i = 0; i < [myCells count]; i++) {
		[[myCells objectAtIndex:i] markWithTetromino:self];
	}
}

-(void)moveDownUnit:(Cell *)oldCell
{
	[self unmarkCell:oldCell];
	Cell *newCell = [tetrisBoard cellAtY:([oldCell y] - 1) x:[oldCell x]];
	assert(![newCell isOccupied]);
	[newCell markWithTetromino:self];
	[myCells addObject:newCell];
}

-(bool)canRotate
{
	return [self canMoveToNewCells:[self transform:YES]];
}

-(bool)canMoveDown
{
	return [self canMoveToNewCells:[self moveByY:-1 x:0]];
}

-(bool)canMoveLeft
{
	return [self canMoveToNewCells:[self moveByY:0 x:-1]];
}

-(bool)canMoveRight
{
	return [self canMoveToNewCells:[self moveByY:0 x:1]];
}

-(bool)canMoveToNewCells:(NSMutableArray *)newCells
{
	if (!newCells) {
		return NO;
	}
	
	Cell *cell;
	for (unsigned int i = 0; i < [newCells count]; i++) {
		cell = [newCells objectAtIndex:i];
		if ([cell isOccupied] && ([myCells indexOfObject:cell] == NSNotFound)) {
			/* Cell is occupied and the occupant isn't myself. */
			return NO;
		}
	}
	return YES;
}

@end
